package com.polytech.diploma.OracleStat.Parsers;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.polytech.diploma.OracleStat.CommandType;

public class FromClauseParser {
	
	protected static String tableNamePattern = "[a-zA-Z](\\w|$|#|){1,29}";
	
	protected static Pattern fromClauseForUpdatePattern = Pattern.compile("UPDATE (" + 
									tableNamePattern + ") ", Pattern.CASE_INSENSITIVE);
	
	protected static Pattern fromClauseForDeletePattern = Pattern.compile("DELETE FROM (" + 
									tableNamePattern /*TABLE_NAME*/ + 
									") WHERE .{1,}", Pattern.CASE_INSENSITIVE);
	
	/**
	 * Single table and multitable INSERT (ALL and FIRST Clause)
	 */
	protected static Pattern fromClauseForInsertPattern = Pattern.compile("INTO (" + 
									tableNamePattern /*TABLE_NAME*/ + 
									") (\\(" /*COLUMN_LIST*/ + 
									"|VALUES|" /*VALUE_LIST*/ + 
									"SELECT).{1,}" /*SUBQUERY*/, 
									Pattern.CASE_INSENSITIVE);
	
	protected static Pattern fromClauseForSelectPattern = Pattern.compile(
			"( |,|\\()*+([a-zA-Z](\\w|$|#|\\_){0,29})", Pattern.CASE_INSENSITIVE);
	
	protected static int SELECT_TABLE_NAME_GROUP = 2;
	protected static int TABLE_NAME_GROUP = 1;
	
	public static List<String> parseFromClause (String sqlQuery, CommandType commandType)
	{
		switch (commandType) {
		case INSERT:
			return parseInsertFromClause(sqlQuery);
		case UPDATE:
			return parseUpdateFromClause(sqlQuery);
		case DELETE:
			return parseDeleteFromClause(sqlQuery);
		default:
			return Collections.EMPTY_LIST;
		}
	}
	
	public static List<String> parseUpdateFromClause(String sqlQuery)
	{
		Matcher tableNameMatcher = fromClauseForUpdatePattern.matcher(sqlQuery);
		
		if(tableNameMatcher.find())
		{
			List<String> tableNameList = new ArrayList<String>();
			tableNameList.add(tableNameMatcher.group(TABLE_NAME_GROUP));
			return tableNameList;
		}
		else
		{
			return Collections.EMPTY_LIST;
		}
	}
	
	public static List<String> parseInsertFromClause(String sqlQuery)
	{
		Matcher tableNameMatcher = fromClauseForInsertPattern.matcher(sqlQuery);
		List<String> tableNameList = new ArrayList<String>();
		
		while(tableNameMatcher.find())
		{
			tableNameList.add(tableNameMatcher.group(TABLE_NAME_GROUP));			
		}
		
		return tableNameList;
	}
	
	public static List<String> parseDeleteFromClause(String sqlQuery)
	{
		Matcher tableNameMatcher = fromClauseForDeletePattern.matcher(sqlQuery);
		
		if(tableNameMatcher.find())
		{
			List<String> tableNameList = new ArrayList<String>();
			tableNameList.add(tableNameMatcher.group(TABLE_NAME_GROUP));
			return tableNameList;
		}
		else
		{
			return Collections.EMPTY_LIST;
		}
	}
	
	public static Set<String> parseSelectFromClause(String sqlQuery)
	{		
		Matcher tableNameMatcher = fromClauseForSelectPattern.matcher(sqlQuery);
		Set<String> tokens = new HashSet<String>();
		while(tableNameMatcher.find())
		{
			tokens.add(tableNameMatcher.group(SELECT_TABLE_NAME_GROUP));
		}
		
		return tokens;
	}	
}
